from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin
from flask import redirect, url_for, flash
from functools import wraps
from app import db, login_manager

# User数据模型
class User(UserMixin, db.Model):
    __tablename__ = "users"
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(64), unique=True, nullable=False)
    password_hash = db.Column(db.String(256), nullable=False)
    role = db.Column(db.String(20), nullable=False, default='guest')  # 角色字段：admin或guest
    
    def set_password(self, password):
        self.password_hash = generate_password_hash(password)
    
    def check_password(self, password):
        return check_password_hash(self.password_hash, password)
    
    def get_id(self):
        return str(self.id)

# 用户加载回调函数
@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

# 权限检查装饰器
def admin_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        from flask_login import current_user
        if not current_user.is_authenticated:
            return redirect(url_for('auth.login'))
        if current_user.role != 'admin':
            flash('权限不足：只有管理员可以访问此页面。')
            return redirect(url_for('main.index'))
        return f(*args, **kwargs)
    return decorated_function


class Student(db.Model):
    __tablename__ = "student"
    id = db.Column(db.Integer, primary_key = True, autoincrement = True, nullable = False)
    name = db.Column(db.String(10), nullable = False)
    age = db.Column(db.Integer, nullable = False)
    major_id = db.Column(db.Integer, db.ForeignKey("majors.id"))

class Major(db.Model):
    __tablename__ = 'majors'
    id = db.Column(db.Integer, primary_key=True)
    major_name = db.Column(db.String(100), unique=True, nullable=False)
    # 定义“一对多”关系中的“一”
    # 'students' 是反向引用的名称，'major' 是在 Student_Info 中定义的 backref 名称
    students = db.relationship('Student', backref='major', lazy='dynamic')
    def __repr__(self):
        return f'<Major {self.major_name}>'